package com.jrx.anytxn.transaction.service.impl;

import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlInterestAccrualLog;
import com.jrx.anytxn.transaction.service.IInterestFileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Service
public class interestFileServiceImpl implements IInterestFileService {

    private static final Logger logger = LoggerFactory.getLogger(interestFileServiceImpl.class);
    @Autowired
    private IOrganizationTableService organizationTableService;

    @Override
    public void mergeFile(PrOrganizationTable org, String filePath, String fileName) throws IOException{
        logger.info("开始合并分库文件");
        Date bussinessDate = org.getToday();
        String toDay = DateUtils.format(bussinessDate,"yyyyMMdd");
        String reportingPath = filePath + org.getTenantId() + File.separator + toDay + File.separator;

        //生成利息计提文件
        mergeReportingFile(reportingPath,toDay, TransBizConstant.FILE_NAME_INTER);
    }

    @Override
    public String createInterFileMessage(TlInterestAccrualLog log) {
        StringBuffer sb = new StringBuffer();
        sb.append((log.getId()==null?"":log.getId()) + TransBizConstant.separator);
        sb.append((log.getAccountType()==null?"":log.getAccountType()) + TransBizConstant.separator);
        sb.append((log.getAccountId()==null?"":log.getAccountId()) + TransBizConstant.separator);
        sb.append((log.getChannel()==null?"":log.getChannel()) + TransBizConstant.separator);
        sb.append((log.getCustomerId()==null?"":log.getCustomerId()) + TransBizConstant.separator);
        sb.append((log.getLoanId()==null?"":log.getLoanId()) + TransBizConstant.separator);
        sb.append((log.getBillingTenor()==null?"":log.getBillingTenor()) + TransBizConstant.separator);
        String accrualDate = log.getAccrualDate()== null ? "" : DateUtils.formatDate(log.getAccrualDate());
        sb.append(accrualDate + TransBizConstant.separator);
        sb.append(log.getDailyRate() + TransBizConstant.separator);
        sb.append((log.getLastTotalAmount()==null?"0.00":log.getLastTotalAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + TransBizConstant.separator);
        sb.append((log.getCurrentTotalAmount()==null?"0.00":log.getCurrentTotalAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + TransBizConstant.separator);
        sb.append(log.getAccrualProvision()==null?"0.00":log.getAccrualProvision().setScale(2, BigDecimal.ROUND_HALF_UP));

        return sb.toString();
    }

    @Override
    public void generatingFile(List<String> messageList, String reportingPath, String fileName, String fileType)  {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        String toDay = DateUtils.format(org.getToday(),"yyyyMMdd");

        String collectionFileName = fileType+ "_" + toDay + "_" + fileName + ".txt";

        String filePath = reportingPath + org.getTenantId() + File.separator + toDay + File.separator;

        Path reportingFile = Paths.get(filePath + collectionFileName);

        Integer i = 0;
        try(FileWriter bfw = new FileWriter(reportingFile.toFile(),true);
            BufferedWriter writer = new BufferedWriter(bfw,10240)) {
            if(reportingFile.toFile().length() != 0){
                writer.write("\r\n");
            }
            for (String message : messageList) {
                i++;
                if(i == messageList.size()){
                    writer.write(message);
                }else{
                    writer.write(message + "\r\n");
                }
            }
            writer.flush();
        } catch (IOException e) {
            logger.error("报送文件生成异常，异常信息：",e);
            throw new RuntimeException(e);
        }
    }

    private void mergeReportingFile(String reportingPath,String toDay,String fileType)  {
        //获取目录下所有文件
        File file = new File(reportingPath);
        File[] tempList = file.listFiles();
        if(tempList == null || tempList.length == 0){
            logger.error("文件合并，未获取到需要合并的文件");
            throw new RuntimeException("文件合并，未获取到需要合并的文件");
        }

        List<File> mergeList = new ArrayList<>();

        for(int i = 0; i < tempList.length; i++){
            String fileName = tempList[i].getName();
            String subStr = fileName.substring(0,fileType.length());
            if(fileType.equals(subStr)){
                mergeList.add(tempList[i]);
            }
        }
        //合并文件
        File resultFile = new File(reportingPath + fileType + "_" + toDay + ".txt");


        Boolean isNullFile = true;
        try(FileChannel resultFileChannel= new FileOutputStream(resultFile, true).getChannel()){
            for(int i = 0; i < mergeList.size(); i++){
                FileChannel blk1 = new FileInputStream(mergeList.get(i)).getChannel();
                if(i == 0 && blk1.size() == 0){
                    resultFile.createNewFile();
                }else if (blk1.size() != 0){
                    if(!isNullFile && i != 0){
                        //换行
                        ByteBuffer buf = ByteBuffer.allocate(48);
                        buf.clear();
                        buf.put("\r\n".getBytes());
                        buf.flip();
                        while(buf.hasRemaining()) {
                            resultFileChannel.write(buf);
                        }
                    }
                    //写入新文件
                    resultFileChannel.transferFrom(blk1, resultFileChannel.size(), blk1.size());
                    isNullFile = false;
                }
                blk1.close();
            }
        } catch (IOException e) {
            logger.error("文件合并异常，异常信息：",e);
            throw new RuntimeException(e);
        }


        // 获取文件总条数
        Long count = null;
        try {
            count = Files.lines(Paths.get(reportingPath + fileType + "_" + toDay + ".txt")).count();
        } catch (IOException e) {
            logger.error("读取文件条数异常：",e);
            throw new RuntimeException(e);
        }
        // 生成OK文件
        File okFile = new File(reportingPath + fileType + "_" + toDay + ".ok");
        try (FileWriter fw = new FileWriter(okFile);
             BufferedWriter writer = new BufferedWriter(fw) ){
            writer.write(count+"");
            writer.flush();
        } catch (IOException e) {
            logger.error("生成OK文件失败");
            throw new RuntimeException(e);
        }
    }
}
